package com.leaf.spring.y201906.day25.arithmetic.activity;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

import com.leaf.spring.y201906.day25.arithmetic.ServerIps;

/**
 * 最小活跃数算法
 * 
 * @Title:
 * @Description:
 * @Author: leaf
 * @Since:2019年6月26日
 * @Version:1.1.0
 */
public class LeastActivityArith {

	// 服务器当前活跃数集合
	private static Map<String, Integer> ACTIVITY_LIST = new LinkedHashMap<>();

	public String getServer() {

		// 初始化
		if (ACTIVITY_LIST.isEmpty()) {
			ServerIps.WEIGHT_LIST.keySet().forEach(ip -> ACTIVITY_LIST.put(ip, 0));
		}

		// 找出当前活跃数最小的服务器
		Optional<Integer> minValue = ACTIVITY_LIST.values().stream().min(Comparator.naturalOrder());

		if (minValue.isPresent()) {

			List<String> minActivityIps = new ArrayList<>();

			ACTIVITY_LIST.forEach((ip, activity) -> {
				if (activity.equals(minValue.get())) {
					minActivityIps.add(ip);
				}
			});

			// 如果最小活跃数的ip有多个，则根据权重来选，权重大的优先
			if (minActivityIps.size() > 1) {

				// 过滤对应的ip和权重
				Map<String, Integer> weightList = new LinkedHashMap<>();

				ServerIps.WEIGHT_LIST.forEach((ip, weight) -> {

					if (minActivityIps.contains(ip)) {
						weightList.put(ip, weight);
					}

				});

				// 如果权重都相等，那么随机一个ip
				int totalWeight = 0;
				boolean sameWeight = true;

				Object[] weightArr = weightList.values().toArray();

				for (int i = 0; i < weightArr.length; i++) {

					Integer weight = (Integer) weightArr[i];
					totalWeight += weight;

					if (sameWeight && i > 0 && weight.equals(weightArr[i - 1])) {
						sameWeight = false;
					}

				}

				int pos = new Random().nextInt(totalWeight);

				// 权重不相等
				if (!sameWeight) {

					for (String ip : weightList.keySet()) {
						Integer weight = weightList.get(ip);
						if (pos < weight) {
							return ip;
						}
						pos -= weight;
					}

				}

				return (String) weightList.keySet().toArray()[new Random().nextInt(weightList.size())];

			}

			// 最小活跃数的ip有1个
			return minActivityIps.get(0);

		}

		return (String) ServerIps.WEIGHT_LIST.keySet().toArray()[new Random().nextInt(ServerIps.WEIGHT_LIST.size())];
	}

	public static void main(String[] args) {

		for (int i = 0; i < 10; i++) {
			System.out.println(new LeastActivityArith().getServer());
		}

	}

}
